Skip to content

Activity Filters - use common dropdown#1649

Merged
prxt6529 merged 3 commits intomainfrom
acticity-filters-common-dropdown
Dec 15, 2025
Merged

Activity Filters - use common dropdown#1649
prxt6529 merged 3 commits intomainfrom
acticity-filters-common-dropdown

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Dec 15, 2025

Summary by CodeRabbit

  • New Features

    • Activity sections now show a loading spinner while fetching and suppress pagination during loading.
  • UI/UX Improvements

    • Dropdown label updated to "Transaction Type".
    • Activity filtering replaced with a more responsive dropdown.
    • Improved empty-state messaging when no activity is available.
  • Tests

    • Updated tests to match the "Transaction Type" UI flow and to validate fetch calls include a non-aborted signal option.

✏️ Tip: You can customize this high-level summary in your review settings.

Signed-off-by: prxt6529 <prxt@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 15, 2025

Walkthrough

Exports dropdown item constants, renames the second dropdown label from "Filter" to "Transaction Type", replaces native Dropdowns with CommonDropdown in meme pages, adds activity loading states and memoized activity content, and updates tests to match the new UI selectors and fetch-option checks.

Changes

Cohort / File(s) Summary
Tests — Label & Selector Updates
__tests__/components/latest-activity/ActivityFilters.test.tsx, __tests__/components/the-memes/MemePageActivity.test.tsx
Updated test queries and expectations to use "Transaction Type" button/menu selectors (switched checks from button[name="Filter"] to button[name="Transaction Type"] and replaced some direct button selections with role="menuitem" item selections).
Tests — Fetch Options Added
__tests__/components/memelab/MemeLabPage.test.tsx
Added expectAbortSignalOptions helper and updated fetchUrl/fetchAllPages expectations to include a second-argument options object verifying a non-aborted AbortSignal.
UI — Activity Filters (exports & label)
components/latest-activity/ActivityFilters.tsx
Added exported constants ActivityContractItems and ActivityTypeItems (removed local useMemo constructions) and changed the second dropdown label to "Transaction Type".
UI — MemeLab Page (activity loading & dropdown)
components/memelab/MemeLabPage.tsx
Added activityLoading state, set loading before/after fetch, introduced memoized activityContent (table / loader / placeholder), replaced inline Bootstrap Dropdown with CommonDropdown using ActivityTypeItems, and adjusted pagination visibility.
UI — Meme Page Activity (activity loading & dropdown)
components/the-memes/MemePageActivity.tsx
Added activityLoading state, loading lifecycle changes around fetch, memoized activityContent, replaced native Dropdown with CommonDropdown, and adjusted layout/pagination to respect loading state.
Utility — CommonDropdown class change
components/utils/select/dropdown/CommonDropdown.tsx
Added tailwind-scope CSS utility class to the outer container div; no behavioral changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Areas to review:
    • activityLoading lifecycle and finally blocks in MemeLabPage.tsx and MemePageActivity.tsx (ensure no stale state or missed resets)
    • correctness of memoization dependencies for activityContent
    • integration and accessibility of CommonDropdown (focus, keyboard, aria roles) and page-reset behavior on filter change
    • tests: updated selectors and added fetch-option assertions (ensure expectations match actual fetch calls)

Possibly related PRs

  • Upcoming subscriptions fix #1645 — Overlapping changes to components/latest-activity/ActivityFilters.tsx and dropdown wiring; likely to touch the same dropdown items/labels.

Suggested reviewers

  • ragnep
  • simo6529

Poem

🐰 I hopped from "Filter" to "Transaction Type" bright,
Spun tiny loaders through the soft UI light,
Dropdowns swapped seats, tests learned a new cue,
Pages wait for fetches, then render anew,
A rabbit applauds — the changes took flight. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: refactoring activity filters to use a CommonDropdown component instead of inline/Bootstrap dropdowns across multiple components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch acticity-filters-common-dropdown

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
components/latest-activity/ActivityFilters.tsx (1)

15-27: Excellent refactoring: Exported constants enable reuse.

Moving these dropdown item arrays to module-level exported constants eliminates redundant useMemo calls and enables reuse across components (MemeLabPage, MemePageActivity). The pattern is clean and improves maintainability.

Optional: Consider freezing these constants to prevent accidental mutation:

-export const ActivityContractItems = Object.values(ContractFilter).map(
+export const ActivityContractItems = Object.freeze(Object.values(ContractFilter).map(
   (contract) => ({
     key: contract,
     label: contract,
     value: contract,
   })
-);
+));

-export const ActivityTypeItems = Object.values(TypeFilter).map((type) => ({
+export const ActivityTypeItems = Object.freeze(Object.values(TypeFilter).map((type) => ({
   key: type,
   label: type,
   value: type,
-}));
+})));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e207bb0 and da28a6a.

📒 Files selected for processing (7)
  • __tests__/components/latest-activity/ActivityFilters.test.tsx (9 hunks)
  • __tests__/components/memelab/MemeLabPage.test.tsx (8 hunks)
  • __tests__/components/the-memes/MemePageActivity.test.tsx (3 hunks)
  • components/latest-activity/ActivityFilters.tsx (2 hunks)
  • components/memelab/MemeLabPage.tsx (9 hunks)
  • components/the-memes/MemePageActivity.tsx (8 hunks)
  • components/utils/select/dropdown/CommonDropdown.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • components/memelab/MemeLabPage.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/the-memes/MemePageActivity.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • components/memelab/MemeLabPage.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/the-memes/MemePageActivity.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • components/memelab/MemeLabPage.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/the-memes/MemePageActivity.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • components/latest-activity/ActivityFilters.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • components/memelab/MemeLabPage.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
  • components/the-memes/MemePageActivity.tsx
**/@(__tests__|*.test).{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Tests should live in __tests__/ or ComponentName.test.tsx; mock external dependencies and APIs in tests

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Place tests in __tests__/ directory or as ComponentName.test.tsx alongside components

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
__tests__/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use Jest + ts-jest for TypeScript testing

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
__tests__/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (tests/AGENTS.md)

__tests__/**/*.{ts,tsx,js}: Prefer for...of loops over forEach as it allows break/continue and works with async/await
Use array.at(-1) and array.at(-2) instead of index-based array access for negative indexing
Use String.prototype.replaceAll() instead of replace() for global string replacements
Use globalThis.fetch() instead of direct fetch() calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Use element.remove() instead of parent.removeChild(element) for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use semantic HTML elements (<label>, <output>) over ARIA attributes when possible; every form control must have a label

Files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
🧠 Learnings (19)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `String.prototype.replaceAll()` instead of `replace()` for global string replacements

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `element.remove()` instead of `parent.removeChild(element)` for DOM manipulation

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Write tests following Arrange – Act – Assert pattern with one behaviour per test and clear, descriptive names

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside components

Applied to files:

  • __tests__/components/latest-activity/ActivityFilters.test.tsx
  • __tests__/components/the-memes/MemePageActivity.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • components/memelab/MemeLabPage.tsx
  • components/utils/select/dropdown/CommonDropdown.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use FontAwesome for icons in React components

Applied to files:

  • components/memelab/MemeLabPage.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/memelab/MemeLabPage.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `globalThis.fetch()` instead of direct `fetch()` calls

Applied to files:

  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests

Applied to files:

  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data

Applied to files:

  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-11-25T08:37:44.688Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: app/api/AGENTS.md:0-0
Timestamp: 2025-11-25T08:37:44.688Z
Learning: Applies to app/api/**/*.{ts,tsx,js,jsx} : Never call `fetch` directly with user-controlled or scraped URLs. Use helpers from `@/lib/security/urlGuard` (`parsePublicUrl`, `assertPublicUrl`, `fetchPublicUrl`, `fetchPublicJson`) to validate URLs against host/IP allowlists and DNS checks before making network requests.

Applied to files:

  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic

Applied to files:

  • __tests__/components/memelab/MemeLabPage.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use TailwindCSS for styling in React components

Applied to files:

  • components/utils/select/dropdown/CommonDropdown.tsx
🧬 Code graph analysis (3)
components/latest-activity/ActivityFilters.tsx (2)
hooks/useActivityData.ts (1)
  • ContractFilter (128-128)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
components/memelab/MemeLabPage.tsx (5)
components/distribution-plan-tool/common/CircleLoader.tsx (1)
  • CircleLoader (9-39)
components/nothingHereYet/NothingHereYetSummer.tsx (1)
  • NothingHereYetSummer (3-19)
components/latest-activity/LatestActivityRow.tsx (1)
  • LatestActivityRow (139-467)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
components/latest-activity/ActivityFilters.tsx (1)
  • ActivityTypeItems (23-27)
components/the-memes/MemePageActivity.tsx (4)
components/distribution-plan-tool/common/CircleLoader.tsx (1)
  • CircleLoader (9-39)
components/nothingHereYet/NothingHereYetSummer.tsx (1)
  • NothingHereYetSummer (3-19)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
components/latest-activity/ActivityFilters.tsx (1)
  • ActivityTypeItems (23-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (13)
components/utils/select/dropdown/CommonDropdown.tsx (1)

109-109: LGTM! CSS scoping class added.

The addition of the tailwind-scope class provides CSS isolation for the dropdown component without altering functionality.

__tests__/components/latest-activity/ActivityFilters.test.tsx (1)

47-47: LGTM! Test expectations updated correctly.

All test assertions have been consistently updated from "Filter:" to "Transaction Type:" to match the updated UI label in the production component.

Also applies to: 59-59, 76-76, 121-121, 160-160, 202-202, 235-235, 255-276

__tests__/components/the-memes/MemePageActivity.test.tsx (1)

127-130: LGTM! Test interactions updated for CommonDropdown.

The test selectors correctly reflect the transition from a native dropdown with "Filter" label to a CommonDropdown with "Transaction Type" label. The interaction pattern now properly targets menu items instead of buttons, aligning with the CommonDropdown's accessibility structure.

Also applies to: 171-173, 204-207

__tests__/components/memelab/MemeLabPage.test.tsx (2)

152-154: LGTM! AbortSignal verification added.

The introduction of expectAbortSignalOptions ensures that all fetch calls properly include an AbortSignal for cleanup, which is essential for preventing memory leaks and race conditions.


342-343: LGTM! Fetch call expectations enhanced.

All fetch call expectations now verify the presence of an AbortSignal, ensuring proper cleanup behavior is tested throughout the component lifecycle.

Also applies to: 357-358, 372-373, 408-409, 427-428, 444-445, 548-549

components/latest-activity/ActivityFilters.tsx (1)

44-54: LGTM! Improved clarity with "Transaction Type" label.

The label change from "Filter" to "Transaction Type" makes the dropdown's purpose more explicit and improves the user experience.

components/memelab/MemeLabPage.tsx (4)

115-115: Excellent loading state management.

The loading state is properly initialized and updated with a finally block ensuring it's reset regardless of fetch success or failure. This pattern prevents stuck loading indicators and race conditions.

Also applies to: 347-347, 386-389


435-464: Well-structured memoized content rendering.

The activityContent memoization provides:

  • Loading state with CircleLoader for visual feedback
  • Empty state with NothingHereYetSummer for clarity
  • Data rendering with proper table structure

The dependencies [activity, activityLoading, nft] are appropriate and prevent unnecessary re-renders.


1351-1373: LGTM! CommonDropdown integration enhances consistency.

The replacement of the native dropdown with CommonDropdown driven by ActivityTypeItems provides:

  • Consistent UI/UX across the application
  • Proper accessibility (aria attributes)
  • Responsive layout with Tailwind utilities
  • Correct state management (resets page on filter change)

1374-1374: Correct conditional pagination rendering.

Pagination only displays when there's activity data and loading is complete, preventing confusing UI states.

components/the-memes/MemePageActivity.tsx (3)

36-36: Excellent loading state implementation.

The loading state follows the same robust pattern as MemeLabPage, with proper initialization and cleanup via the finally block. This ensures consistent UX and prevents race conditions.

Also applies to: 47-47, 76-79


92-121: Well-designed memoized activity content.

The activityContent memoization mirrors the pattern in MemeLabPage, providing:

  • Loading indicator with CircleLoader
  • Empty state with NothingHereYetSummer
  • Activity table when data is available

Dependencies [activity, activityLoading, props.nft] are correctly scoped.


187-210: LGTM! Consistent CommonDropdown implementation.

The CommonDropdown integration matches the pattern established in MemeLabPage and ActivityFilters, ensuring:

  • UI/UX consistency across the application
  • Proper filter state management with page reset
  • Responsive layout with Tailwind utilities
  • Conditional pagination display

Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
components/the-memes/MemePageActivity.tsx (1)

92-124: Consider checking loading state first for consistent UX.

Currently, when activityLoading is true but activity.length > 0 (e.g., when switching filters with existing data), the old activity table is displayed without any loading indication. This creates an inconsistent experience compared to the initial load.

Consider reordering the conditions to always show the loader during loading:

 const activityContent = useMemo(() => {
+  if (activityLoading) {
+    return (
+      <div className="tw-flex tw-justify-center tw-items-center tw-py-4">
+        <CircleLoader size={CircleLoaderSize.LARGE} />
+      </div>
+    );
+  }
+
   if (activity.length > 0) {
     return (
       <Table bordered={false} className={styles.transactionsTable}>
         <tbody>
           {activity.map((tr) => (
             <LatestActivityRow
               tr={tr}
               nft={props.nft}
               key={`${tr.from_address}-${tr.to_address}-${tr.transaction}-${tr.token_id}`}
             />
           ))}
         </tbody>
       </Table>
     );
   }

-  if (activityLoading) {
-    return (
-      <div className="tw-flex tw-justify-center tw-items-center tw-py-4">
-        <CircleLoader size={CircleLoaderSize.LARGE} />
-      </div>
-    );
-  }
-
-  if (activity.length === 0) {
-    return (
-      <div className="tw-flex tw-justify-center tw-items-center tw-h-full tw-py-2">
-        <NothingHereYetSummer />
-      </div>
-    );
-  }
+  return (
+    <div className="tw-flex tw-justify-center tw-items-center tw-h-full tw-py-2">
+      <NothingHereYetSummer />
+    </div>
+  );
 }, [activity, activityLoading, props.nft]);
components/memelab/MemeLabPage.tsx (1)

435-467: Consider checking loading state first and extracting shared logic.

This activityContent logic has two opportunities for improvement:

  1. Condition order: Same issue as MemePageActivity.tsx - when loading with existing data, the old table is shown without loading indication. Consider checking activityLoading first.

  2. Code duplication: This logic is nearly identical to MemePageActivity.tsx (lines 92-124). Consider extracting to a shared hook or component for better maintainability.

Example of extracting to a shared hook:

function useActivityContent(
  activity: Transaction[],
  activityLoading: boolean,
  nft?: NFT | LabNFT
) {
  return useMemo(() => {
    if (activityLoading) {
      return (
        <div className="tw-flex tw-justify-center tw-items-center tw-py-4">
          <CircleLoader size={CircleLoaderSize.LARGE} />
        </div>
      );
    }

    if (activity.length > 0) {
      return (
        <Table bordered={false} className={styles.transactionsTable}>
          <tbody>
            {activity.map((tr) => (
              <LatestActivityRow
                tr={tr}
                nft={nft}
                key={`${tr.from_address}-${tr.to_address}-${tr.transaction}-${tr.token_id}`}
              />
            ))}
          </tbody>
        </Table>
      );
    }

    return (
      <div className="tw-flex tw-justify-center tw-items-center tw-h-full tw-py-2">
        <NothingHereYetSummer />
      </div>
    );
  }, [activity, activityLoading, nft]);
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7062cb0 and d7a234f.

📒 Files selected for processing (2)
  • components/memelab/MemeLabPage.tsx (9 hunks)
  • components/the-memes/MemePageActivity.tsx (8 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version

**/*.{ts,tsx,js,jsx}: Replace <img> elements with <Image /> from next/image to satisfy @next/next/no-img-element ESLint rule
Use <Link href="/path"> from Next.js for internal navigation instead of plain HTML links to satisfy @next/next/no-html-link-for-pages ESLint rule

Files:

  • components/the-memes/MemePageActivity.tsx
  • components/memelab/MemeLabPage.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always add readonly before props in React components

Files:

  • components/the-memes/MemePageActivity.tsx
  • components/memelab/MemeLabPage.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use <Link>, images should use next/image, and adopt Next's ESLint rules (Core Web Vitals)

**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)

Files:

  • components/the-memes/MemePageActivity.tsx
  • components/memelab/MemeLabPage.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Must pass tsc --noEmit type checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") over React. namespace usage (React.useMemo, React.useRef, etc.)
If the react-hooks/exhaustive-deps lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in useEffectEvent

**/*.{ts,tsx}: Must pass tsc --noEmit for TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
Use useEffectEvent for non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs: <Link> for internal links, next/image for images, adopt Next's ESLint rules
Use 'use cache' directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace <img> elements with <Image /> from next/image
Use <Link href="/path"> for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with 'use server' directive

Files:

  • components/the-memes/MemePageActivity.tsx
  • components/memelab/MemeLabPage.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions

Applied to files:

  • components/memelab/MemeLabPage.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use FontAwesome for icons in React components

Applied to files:

  • components/memelab/MemeLabPage.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks

Applied to files:

  • components/memelab/MemeLabPage.tsx
🧬 Code graph analysis (2)
components/the-memes/MemePageActivity.tsx (5)
components/latest-activity/LatestActivityRow.tsx (1)
  • LatestActivityRow (139-467)
components/distribution-plan-tool/common/CircleLoader.tsx (1)
  • CircleLoader (9-39)
components/nothingHereYet/NothingHereYetSummer.tsx (1)
  • NothingHereYetSummer (3-19)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
components/latest-activity/ActivityFilters.tsx (1)
  • ActivityTypeItems (23-29)
components/memelab/MemeLabPage.tsx (4)
components/distribution-plan-tool/common/CircleLoader.tsx (1)
  • CircleLoader (9-39)
components/nothingHereYet/NothingHereYetSummer.tsx (1)
  • NothingHereYetSummer (3-19)
components/utils/select/dropdown/CommonDropdown.tsx (1)
  • CommonDropdown (11-187)
components/latest-activity/ActivityFilters.tsx (1)
  • ActivityTypeItems (23-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (7)
components/the-memes/MemePageActivity.tsx (4)

3-10: LGTM!

The new imports are appropriate and align with the refactoring to use common components for activity filtering and loading states.

Also applies to: 19-19


36-36: LGTM!

The loading state is properly managed with the finally block ensuring cleanup regardless of fetch success or failure.

Also applies to: 47-47, 76-79


190-207: LGTM!

The responsive header layout with the CommonDropdown provides a clean, accessible interface. Resetting the page to 1 when the filter changes is the correct behavior to avoid showing an empty result set from an out-of-bounds page.


211-211: LGTM!

The rendering integration is clean, and hiding pagination during loading prevents user confusion about available pages.

Also applies to: 213-213

components/memelab/MemeLabPage.tsx (3)

7-11: LGTM!

The imports and loading state initialization align with the established pattern from MemePageActivity.tsx.

Also applies to: 60-60, 115-115


347-347: LGTM!

Loading state is properly managed with appropriate cleanup in the finally block.

Also applies to: 386-389


1354-1372: LGTM!

The responsive layout and rendering integration mirror the improvements in MemePageActivity.tsx, providing a consistent user experience across both pages.

Also applies to: 1375-1375, 1377-1377

@prxt6529 prxt6529 merged commit 395cdea into main Dec 15, 2025
8 checks passed
@prxt6529 prxt6529 deleted the acticity-filters-common-dropdown branch December 15, 2025 11:58
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
19.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@coderabbitai coderabbitai Bot mentioned this pull request Jan 3, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants